﻿
namespace Amplify.Twitter
{
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.ServiceModel.Security;
	using System.Text;


	/// <summary>
	/// Manages the interactions of the user with information on tweets/stats messages on twitter
	/// </summary>
	public class StatusClient : TwitterClient<IStatusClient>
	{



		/// <summary>
		/// Initializes a new instance of the <see cref="StatusClient"/> class.
		/// </summary>
		/// <param name="username">The username.</param>
		/// <param name="password">The password.</param>
		public StatusClient(string username, string password)
			: base(username, password)
		{
			
		}

		/// <summary>
		/// Gets an array of <see cref="Amplify.Twitter.Status"/> that are replies.
		/// </summary>
		/// <returns>returns an array of <see cref="Amplify.Twitter.Status"/>.</returns>
		/// <exception cref="System.ServiceModel.Security.MessageSecurityException" />
		/// <exception cref="Amplify.Twitter.TwitterException"> Throws when a twitter error occurs. </exception>
		public Status[] GetReplies()
		{
			return this.GetReplies(new DefaultOptions());	
		}


		/// <summary>
		/// Gets an array of <see cref="Amplify.Twitter.Status"/> that are replies.
		/// </summary>
		/// <param name="options"> The <see cref="Amplify.Twitter.DefaultOptions"/> to get the list of replies. </param>
		/// <returns>returns an array of <see cref="Amplify.Twitter.Status"/>.</returns>
		/// <exception cref="System.ServiceModel.Security.MessageSecurityException" />
		/// <exception cref="Amplify.Twitter.TwitterException"> Throws when a twitter error occurs. </exception>
		public Status[] GetReplies(DefaultOptions options)
		{
			try 
			{ 
				return this.GetReplies(
					options.Page,
					options.SinceId,
					options.SinceValue);
			}
			catch(MessageSecurityException securityException) 
			{
				this.Rescue(securityException);
			}
			return null;
		}


		/// <summary>
		/// Gets an array of <see cref="Amplify.Twitter.Status"/> that are replies.
		/// </summary>
		/// <param name="page">The page number (for paging). </param>
		/// <param name="since">Specify a search date for all the friends that have joined since.  </param>
		/// <param name="sinceId">Specify a integer for all ids to be greater than. </param>
		/// <returns>returns an array of <see cref="Amplify.Twitter.Status"/>.</returns>
		/// <exception cref="System.ServiceModel.Security.MessageSecurityException" />
		/// <exception cref="Amplify.Twitter.TwitterException"> Throws when a twitter error occurs. </exception>
		public Status[] GetReplies(int page, int sinceId, string since)
		{
			try
			{
				return this.Proxy.GetReplies(page, sinceId, since);
			}
			catch(MessageSecurityException securityException) 
			{
				this.Rescue(securityException);
			}
			return null;
		}
		

		/// <summary>
		/// Gets the user timeline of tweets (statuses).
		/// </summary>
		/// <returns>returns an array of <see cref="Amplify.Twitter.Status"/>. </returns>
		/// <exception cref="Amplify.Twitter.TwitterException"> Throws when a twitter error occurs. </exception>
		public Status[] GetUserTimeline()
		{
			return this.GetUserTimeline(this.Username);
		}

		/// <summary>
		/// Gets the user timeline of tweets (statuses).
		/// </summary>
		/// <param name="id">The screen name or id of the user.</param>
		/// <returns>returns an array of <see cref="Amplify.Twitter.Status"/>. </returns>
		/// <exception cref="Amplify.Twitter.TwitterException"> Throws when a twitter error occurs. </exception>
		public Status[] GetUserTimeline(object id)
		{
			return this.GetUserTimeline(id, new TimelineOptions());
		}


		/// <summary>
		/// Gets the user timeline of tweets (statuses).
		/// </summary>
		/// <param name="id">The screen name or id of the user.</param>
		/// <param name="options"> The optional parameters. </param>
		/// <returns>returns an array of <see cref="Amplify.Twitter.Status"/> of <see cref="Amplify.Twitter.Status"/>. </returns>
		/// <exception cref="Amplify.Twitter.TwitterException"> Throws when a twitter error occurs. </exception>
		public Status[] GetUserTimeline(object id, TimelineOptions options)
		{
			if (id == null || !(id is string || id is int))
				throw new TwitterException("The id can not be null, it must be a string screen name or integer user id");
			try {
				return this.Proxy.GetUserTimeline(
					id.ToString(),
					options.Count,
					options.Page,
					options.SinceId,
					options.SinceValue);
			}
			catch(MessageSecurityException securityException) 
			{
				this.Rescue(securityException);
			}
			return null;
		}


		/// <summary>
		/// Gets the friends timeline of tweets (statuses).
		/// </summary>
		/// <returns>returns an array of <see cref="Amplify.Twitter.Status"/>. </returns>
		/// <exception cref="Amplify.Twitter.TwitterException"> Throws when a twitter error occurs. </exception>
		public Status[] GetFriendsTimeline()
		{
			return this.GetFriendsTimeline(new TimelineOptions());
		}

		/// <summary>
		/// Gets the friends timeline of tweets (statuses).
		/// </summary>
		/// <param name="options"> The optional parameters. </param>
		/// <returns>returns a <see cref="Amplify.Twitter.Status"/>. </returns>
		/// <exception cref="Amplify.Twitter.TwitterException"> Throws when a twitter error occurs. </exception>
		public Status[] GetFriendsTimeline(TimelineOptions options)
		{
			try {
				return this.Proxy.GetFriendsTimeline(
					options.Count,
					options.Page,
					options.SinceId,
					options.SinceValue);
			}
			catch (MessageSecurityException securityException)
			{
				this.Rescue(securityException);
			}
			return null;
		}


		/// <summary>
		/// Gets the friends timeline.
		/// </summary>
		/// <param name="count">The count.</param>
		/// <param name="page">The page.</param>
		/// <param name="sinceId">The since id.</param>
		/// <param name="since">The since.</param>
		/// <returns>returns a <see cref="Amplify.Twitter.Status"/>. </returns>
		/// <exception cref="Amplify.Twitter.TwitterException"> Throws when a twitter error occurs. </exception>
		public Status[] GetFriendsTimeline(int count, int page, int sinceId, string since)
		{
			try
			{
				return this.Proxy.GetFriendsTimeline(
					count, page, sinceId, since);
			}
			catch(MessageSecurityException securityException) 
			{
				this.Rescue(securityException);
			}
			return null;
		}


		/// <summary>
		/// Gets the public timeline of tweets (statuses).
		/// </summary>
		/// <returns>returns an array of <see cref="Amplify.Twitter.Status"/>. </returns>
		/// <exception cref="Amplify.Twitter.TwitterException"> Throws when a twitter error occurs. </exception>
		public Status[] GetPublicTimeline()
		{
			return this.GetPublicTimeline(new TimelineOptions());
		}

		/// <summary>
		/// Gets the public timeline of tweets (statuses).
		/// </summary>
		/// <param name="options"> The optional parameters. </param>
		/// <returns>returns an array of <see cref="Amplify.Twitter.Status"/> list. </returns>
		/// <exception cref="Amplify.Twitter.TwitterException"> Throws when a twitter error occurs. </exception>
		public Status[] GetPublicTimeline(TimelineOptions options)
		{
			try {
				return this.Proxy.GetPublicTimeline(
						options.Count,
						options.Page,
						options.SinceId,
						options.SinceValue);
			}
			catch(MessageSecurityException securityException) 
			{
				this.Rescue(securityException);
			}
			return null;
		}

		/// <summary>
		/// Gets the user timeline.
		/// </summary>
		/// <param name="id">The screen name or id of the user.</param>
		/// <param name="count">The count of records to return. Can not exceed 200. </param>
		/// <param name="page">The page number to return for paging purposes. </param>
		/// <param name="sinceId">The integer id that says to bring back that message and everything after that message. </param>
		/// <param name="since">The date/time minimum of how far to go back. </param>
		/// <returns>returns an array of <see cref="Amplify.Twitter.Status"/>. </returns>
		/// <exception cref="Amplify.Twitter.TwitterException"> Throws when a twitter error occurs. </exception>
		public Status[] GetUserTimeline(string id, int count, int page, int sinceId, string since)
		{
			try{
				return this.Proxy.GetUserTimeline(id, count, page, sinceId, since);
			}
			catch (MessageSecurityException securityException)
			{
				this.Rescue(securityException);
			}
			return null;
		}

		/// <summary>
		/// Creates a tweet on twitter.
		/// </summary>
		/// <param name="text">The textual content of the message.</param>
		/// <returns>returns a <see cref="Amplify.Twitter.Status"/> object. </returns>
		/// <exception cref="Amplify.Twitter.TwitterException"> Throws when a twitter error occurs. </exception>
		public Status Create(string text)
		{
			if (text.Length > 140)
				throw new TwitterException("A tweet message can not exceed 140 characters in length.");

			try 
			{
				return this.Proxy.Create(text);
			}
			catch(MessageSecurityException securityException) 
			{
				this.Rescue(securityException);
			}
			return null;

		}


		/// <summary>
		/// Destroys the specified tweet.
		/// </summary>
		/// <param name="statusId">The id of the status/tweet to destroy.</param>
		/// <returns>returns a <see cref="Amplify.Twitter.Status"/> object. </returns>
		/// <exception cref="Amplify.Twitter.TwitterException"> Throws when a twitter error occurs. </exception>
		public Status Destroy(int statusId)
		{
			return this.Destroy(statusId.ToString());
		}

		/// <summary>
		/// Destroys the specified tweet.
		/// </summary>
		/// <param name="statusId">The id of the status/tweet to destroy.</param>
		/// <returns>returns a <see cref="Amplify.Twitter.Status"/> object. </returns>
		/// <exception cref="Amplify.Twitter.TwitterException"> Throws when a twitter error occurs. </exception>
		public Status Destroy(string statusId)
		{
			try 
			{
				return this.Proxy.Destroy(statusId);
			}
			catch(MessageSecurityException securityException) 
			{
				this.Rescue(securityException);
			}
			return null;
			
		}

		/// <summary>
		/// Shows the specified tweet.
		/// </summary>
		/// <param name="statusId">The id of the status/tweet to show.</param>
		/// <returns>returns a <see cref="Amplify.Twitter.Status"/> object. </returns>
		/// <exception cref="Amplify.Twitter.TwitterException"> Throws when a twitter error occurs. </exception>
		public Status Show(string statusId)
		{
			try
			{
				return this.Proxy.Show(statusId);
			}
			catch(MessageSecurityException securityException) 
			{
				this.Rescue(securityException);
			}
			return null;
		}


		/// <summary>
		/// Shows the specified tweet.
		/// </summary>
		/// <param name="statusId">The id of the status/tweet to show.</param>
		/// <returns>returns a <see cref="Amplify.Twitter.Status"/> object. </returns>
		/// <exception cref="Amplify.Twitter.TwitterException"> Throws when a twitter error occurs. </exception>
		public Status Show(int statusId)
		{
			return this.Show(statusId.ToString());
		}
	}
}
